mod controllers;
mod entities;
mod middlewares;
mod repositories;
mod routes;
mod services;
mod utils;

use std::sync::Arc;
use crate::middlewares::db_datasource::get_db_connect;
use crate::middlewares::filter::default_filter::DefaultFilter;
use crate::middlewares::redis_client;
use crate::routes::routes::configure_user_routes;
use actix_web::{middleware, web, App, HttpServer};
use log::{error, info};
use middlewares::logging::init_logger;
use std::time::Duration;
use utils::env_setting_center::{default_not_found_page, get_address};
use key_management::key_manager::key_initialization::init_keys;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    println!("Program started!");
    // init logger
    init_logger();
    // get database connection pool
    let pool = match get_db_connect().await {
        Ok(pool) => {
            info!("Database pool created successfully");
            pool
        }
        Err(e) => {
            error!("Failed to create database pool: {:?}", e);
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Database connection failed",
            ));
        }
    };

    error!("test redis redis begin=======");
    let redis = redis_client::get_redis_client().await;
    redis
        .set(
            "name",
            "huawei ra redis test.",
            Some(Duration::from_secs(3600)),
        )
        .expect("add redis num failed");
    error!("test redis redis end=======");
    // init keys
    init_keys().await.unwrap();

    // start server
    info!("Starting server at env ADDRESS");
    HttpServer::new(move || {
        let pool = Arc::clone(&pool);
        App::new()
            .app_data(web::Data::new(pool))
            .wrap(middleware::Logger::default())
            .wrap(DefaultFilter)
            .configure(configure_user_routes)
            .default_service(web::route().to(default_not_found_page))
    })
    .bind(get_address())?
    .run()
    .await
}
